Skip to content

WIP: TypeScript typings #51

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 4 commits into from
Closed

Conversation

saraedum
Copy link

@saraedum saraedum commented Nov 9, 2018

resolves #25

@saraedum
Copy link
Author

saraedum commented Nov 9, 2018

I am not a TypeScript expert but this works for me. Please let me know what you think and thanks for this very useful extension :)

@saraedum
Copy link
Author

saraedum commented Nov 9, 2018

To try out these typings in your project, you can temporarily add

yarn add https://github.com/saraedum/vue-async-computed\#87a833fdd0a89f48d1fb675b3899356d0599fdf2

instead of vue-async-computed.

@oscar-gardiazabal
Copy link

oscar-gardiazabal commented Nov 17, 2018

I copied your index.d.ts into my project, and asyncComputed property warning is solved. But if I call an asyncComputed method from anywhere says:
Property 'xxx' does not exist on type 'CombinedVueInstance<Vue, { ...
(vscode)

@saraedum
Copy link
Author

@trollderius, you are right, that part is still missing. Let me see if I can get that to work as well.

@oscar-gardiazabal
Copy link

My workaround here is using an 'any' interface, but the sad thing is all types correlations are lost.

interface AsyncComputedObject {
  [K: string]: any;
}

(this as AsyncComputedObject).xxx

@saraedum
Copy link
Author

saraedum commented Nov 18, 2018

I think it's quite hard to get the typings completely right here. You'd have to augment constructions like this one basically:

export interface VueConstructor<V extends Vue = Vue> {
  new <Data = object, Methods = object, Computed = object, PropNames extends string = never>(options?: ThisTypedComponentOptionsWithArrayProps<V, Data, Methods, Computed, PropNames>): CombinedVueInstance<V, Data, Methods, Computed, Record<PropNames, any>>;

I.e., add a new generic parameter ComputedAsync = object and then augment all the places where this is used. It's not impossible I think, but it won't work anymore when using some other package that does something similar. Also, it's probably quite dependent on Vue.js' exact typing setup.

So I was wondering, why is asyncComputed actually a new property in the component options? What if we marked computed properties that are "async" with an extra key instead?

This seems to work and I pushed a proof-of-concept to this PR. (We should of course not replace all the old tests, I just wanted to see that this actually works and that typescript was happy with the tests now.)

@saraedum saraedum changed the title added TypeScript typings WIP: TypeScript typings Nov 18, 2018
this is a proof of concept that asyncComputed can be merged into computed and
the distinction between a normal computed and an async-computed can be made by
an extra keyword. The upside of this is that it fixes typings as we can rely on
the standard typings that come with Vue.js' computed properties.
@saraedum
Copy link
Author

@foxbenjaminfox is there a strong reason why vue-async-computed could not support computed properties with asynchronous: true as I am doing (in this hack) here?

saraedum added a commit to saraedum/vue-async-computed that referenced this pull request Nov 24, 2018
@saraedum
Copy link
Author

saraedum commented Dec 6, 2018

I am not sure whether it's possible to get the types right. My most promising attempt so far was

declare module "vue/types/options" {
	interface ComputedOptions<T> {
		asynchronous?: (() => T | Promise<T>) | {
			get: (() => T | Promise<T>);
			default?: T;
			lazy?: boolean;
		};
	}
}

With this I can set a computed's asynchronous such as

computed: {
  x: {
      asynchronous(): Promise<string> { return Promise.resolve(…) }
  }
}

and TypeScript knows that this.x is a string.

I got this to work mostly (strangely it does not work in Vue.extend.) However, there is no way to make vue-property-decorator work properly. I would have liked to be able to write a decorator such as

@asynchronous
get x() {
  return Promise.resolve(…);
}

However decorators in TypeScript can not modify the return type yet, so this did not work.

@saraedum
Copy link
Author

saraedum commented Dec 6, 2018

So, I am not satisfied with the current state of this and I don't have more time to invest here.

@saraedum saraedum closed this Dec 6, 2018
this is a hack and it does not fully work unfortunately. I simplified the code
for this to drop the distinction of lazy/non-lazy props.
@saraedum saraedum reopened this Dec 6, 2018
@saraedum saraedum closed this Dec 6, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Typescript
2 participants